#include "Tank.h"
#include <string>
#include "PlayScenarioPanel.h"

Tank::Tank(SDL_Surface* surface,int posX, int posY, Widget *parent, std::string owner, int angle,
		bool flaged) :
		Widget(posX, posY, parent) {

	std::stringstream ss;
	ss << "owner: " << owner;
//	Logger::log("tank", "constructor", &ss);

	this->owner = owner;
	this->flaged = flaged;

	tankSurface =surface;
	parcel = getPosition();
	parcel.height = 30;
	parcel.width = 30;
	nextX = parcel.posX;
	nextY = parcel.posY;

	goingBackwards = false;
	goingForward = false;
	turningLeft = false;
	turningRight = false;
	shooting = false;
	this->angle = angle;

	lblName = NULL;

}

void Tank::updateFlag(){
	this->flaged =true;
}

void Tank::handleEvent(Event event) {
	/*std::stringstream owner;
	 owner << "owner: " << this->owner;

	 Logger::log("tank", "handleEvent", &owner);*/

	//Si se cumple la segunda condicion es que es un evento de teclado y tengo q modificar el tanque del que soy dueno
	if (event.getSender() == this->owner || (event.getSender().empty() && this->flaged)) {

		switch (event.getKey()) {
		case KeyDown:
			if (event.getType() == KeyPressed) {
				goingBackwards = true;
			} else if (event.getType() == KeyReleased) {
				goingBackwards = false;
			}
			break;
		case KeyUp:
			if (event.getType() == KeyPressed) {
				goingForward = true;
			} else if (event.getType() == KeyReleased) {
				goingForward = false;
			}
			break;
		case KeyLeft:
			if (event.getType() == KeyPressed) {
				turningLeft = true;
			} else if (event.getType() == KeyReleased) {
				turningLeft = false;
			}
			break;
		case KeyRight:
			if (event.getType() == KeyPressed) {
				turningRight = true;
			} else if (event.getType() == KeyReleased) {
				turningRight = false;
			}
			break;
		case Space:
			if (event.getType() == KeyPressed)  {
				//Creo la bala y la agrego al scenario
				((PlayScenarioPanel*)parent)->addBullet(this->nextX,this->nextY,angle);
			}
			break;
		default:
			break;
		}

	}
}

void Tank::resolve() {
	if (turningLeft) {
		if (angle == 350.0) {
			angle = 0.0;
		} else {
			angle += 10.0;
		}

		std::stringstream ss;
//		ss << "angulo despues de rotar a la izq: " << angle;

//		Logger::log("tank", "resolve", &ss);

	}

	if (turningRight) {
		if (angle == 0.0) {
			angle = 350.0;
		} else {
			angle -= 10.0;
		}

		std::stringstream ss;
//		ss << "angulo despues de rotar a la der: " << angle;

//		Logger::log("tank", "resolve", &ss);

	}

	if (goingForward) {
		if ((angle >= 0.0) && (angle <= 90.0)) {

			int avanceY, avanceX;

			avanceY = (-(angle / 10));
			avanceX = avanceY + 9;

			nextX = parcel.posX + avanceX;
			nextY = parcel.posY + avanceY;

			std::stringstream ss1;
//			ss1 << "nextX = " << nextX << " - nextY = " << nextY;

//			Logger::log("tank", "resolve", &ss1);

		} else if ((angle > 90.0) && (angle <= 180.0)) {

			int avanceY, avanceX;

			avanceX = (-(angle - 90)) / 10;
			avanceY = -avanceX - 9;

			nextX = parcel.posX + avanceX;
			nextY = parcel.posY + avanceY;

			std::stringstream ss1;
//			ss1 << "nextX = " << nextX << " - nextY = " << nextY;

//			Logger::log("tank", "resolve", &ss1);

		} else if ((angle > 180) && (angle <= 270)) {

			int avanceY, avanceX;

			avanceY = (angle - 180) / 10;
			avanceX = avanceY - 9;

			nextX = parcel.posX + avanceX;
			nextY = parcel.posY + avanceY;

			std::stringstream ss1;
//			ss1 << "nextX = " << nextX << " - nextY = " << nextY;

//			Logger::log("tank", "resolve", &ss1);

		} else if ((angle >= 270) && (angle <= 360)) {

			int avanceY, avanceX;

			avanceX = ((angle - 270) / 10);
			avanceY = -avanceX + 9;

			nextX = parcel.posX + avanceX;
			nextY = parcel.posY + avanceY;

			std::stringstream ss1;
//			ss1 << "nextX = " << nextX << " - nextY = " << nextY;

//			Logger::log("tank", "resolve", &ss1);

		}
	}
	if (goingBackwards) {
		if ((angle >= 0.0) && (angle <= 90.0)) {

			int avanceY, avanceX;

			avanceY = (-(angle / 10));
			avanceX = avanceY + 9;

			nextX = parcel.posX - avanceX;
			nextY = parcel.posY - avanceY;

			std::stringstream ss1;
//			ss1 << "nextX = " << nextX << " - nextY = " << nextY;

			Logger::log("tank", "resolve", &ss1);

		} else if ((angle > 90.0) && (angle <= 180.0)) {

			int avanceY, avanceX;

			avanceX = (-(angle - 90)) / 10;
			avanceY = -avanceX - 9;

			nextX = parcel.posX - avanceX;
			nextY = parcel.posY - avanceY;

			std::stringstream ss1;
//			ss1 << "nextX = " << nextX << " - nextY = " << nextY;

//			Logger::log("tank", "resolve", &ss1);

		} else if ((angle > 180) && (angle <= 270)) {

			int avanceY, avanceX;

			avanceY = (angle - 180) / 10;
			avanceX = avanceY - 9;

			nextX = parcel.posX - avanceX;
			nextY = parcel.posY - avanceY;

			std::stringstream ss1;
//			ss1 << "nextX = " << nextX << " - nextY = " << nextY;

			Logger::log("tank", "resolve", &ss1);

		} else if ((angle >= 270) && (angle <= 360)) {

			int avanceY, avanceX;

			avanceX = ((angle - 270) / 10);
			avanceY = -avanceX + 9;

			nextX = parcel.posX - avanceX;
			nextY = parcel.posY - avanceY;

			std::stringstream ss1;
//			ss1 << "nextX = " << nextX << " - nextY = " << nextY;

//			Logger::log("tank", "resolve", &ss1);

		}
	}
	if (nextX > 10 && nextX + parcel.width < 810) {
		parcel.posX = nextX;
	}
	if (nextY > 10 && nextY + parcel.height < 610) {
		parcel.posY = nextY;
	}

	if (lblName != NULL) {
		delete lblName;
	}
	lblName = new Label(owner, parent, parcel.posX - parcel.width / 2,
			parcel.posY - parcel.height / 2 - 5, 10);

}

void Tank::showOn(SDL_Surface* surface) {
	SDL_Rect rectSrc;
	rectSrc.x = angle * 3;
	rectSrc.y = 0;
	rectSrc.w = parcel.width;
	rectSrc.h = parcel.height;

	SDL_Rect rectDest;
	rectDest.x = parcel.posX;
	rectDest.y = parcel.posY;
	rectDest.w = parcel.width;
	rectDest.h = parcel.height;

	SDL_BlitSurface(tankSurface, &rectSrc, surface, &rectDest);

	if(lblName)
		lblName->showOn(surface);
}

int Tank::getBulletAngle() {
	return angle;
}

Tank::~Tank() {
	SDL_FreeSurface(tankSurface);
}

int Tank::getbulletX() {
	return (parcel.posX - 10);
}

int Tank::getbulletY() {
	return (parcel.posY - 10);
}

std::string Tank::getOwner() {
	return owner;
}

TankStatus Tank::getTankStatus() {
	Parcel parcela;
	parcela = getPosition();

	return TankStatus(owner, parcela.posX, parcela.posY, angle);
}

void Tank::updateStatus(DTOCliente* cliente) {
	this->angle = cliente->getAngle();
	this->nextX = cliente->getPosX();
	this->nextY = cliente->getPosY();
}
